package cn.sciento.transfer.infra.data.check.mapping;

import cn.sciento.core.exception.CommonException;import java.nio.ByteBuffer;
import cn.sciento.transfer.infra.data.check.constant.SerializeType;
import org.springframework.util.Assert;

public class MappedIndex {
  private static final byte MAGIC = SerializeType.INDEX.getType();
  
  private Long id;
  
  private Long offset;
  
  private byte[] md5Digit;
  
  public MappedIndex(Long id, byte[] md5Digit, Long offset) {
    this.id = id;
    Assert.isTrue((md5Digit.length == 16), "digit length is not right");
    this.md5Digit = md5Digit;
    this.offset = offset;
  }
  
  public ByteBuffer encode() {
    int size = calLength();
    ByteBuffer byteBuffer = ByteBuffer.allocate(size);
    byteBuffer.put(MAGIC);
    byteBuffer.putLong(this.id.longValue());
    byteBuffer.putLong(this.offset.longValue());
    byteBuffer.put(this.md5Digit);
    return byteBuffer;
  }
  
  public MappedIndex decode(byte[] bs) {
    Assert.isTrue((bs.length == calLength()), "invalid index bytes");
    ByteBuffer byteBuffer = ByteBuffer.wrap(bs);
    if (SerializeType.valueOf(byteBuffer.get()) != SerializeType.INDEX)
      throw new CommonException("The file was maliciously modified");
    Long id = byteBuffer.getLong();
    Long offset = byteBuffer.getLong();
    byte[] digest = new byte[this.md5Digit.length];
    byteBuffer.get(digest, 0, digest.length);
    return new MappedIndex(id, digest, offset);
  }
  
  public int calLength() {
    int size = 0;
    size++;
    size += 8;
    size += 16;
    size += 8;
    return size;
  }
  
  public Long getId() {
    return this.id;
  }
  
  public void setId(Long id) {
    this.id = id;
  }
  
  public byte[] getMd5Digit() {
    return this.md5Digit;
  }
  
  public void setMd5Digit(byte[] md5Digit) {
    this.md5Digit = md5Digit;
  }
  
  public long getOffset() {
    return this.offset.longValue();
  }
}
